package com.example.show_auto.utils

import com.example.show_auto.data.Chef
import com.example.show_auto.data.Equip
import com.example.show_auto.data.Recipe
import com.example.show_auto.data.Skill
import com.example.show_auto.ui.pages.UltimateSkillsState

/**
 * 厨具推荐计算器
 * 根据厨师的菜谱制作品级来推荐合适的厨具
 */
object EquipRecommendationCalculator {

    /**
     * 推荐结果数据类
     */
    data class RecommendationResult(
        val needRecommendation: Boolean, // 是否需要推荐
        val targetRecipes: List<Recipe>, // 目标菜谱（需要提升品级的菜谱）
        val recommendedEquips: List<EquipRecommendation> // 推荐的厨具列表
    )

    /**
     * 厨具推荐数据类
     */
    data class EquipRecommendation(
        val equip: Equip,
        val totalSkillBonus: Int, // 总技法加成值
        val affectedRecipes: List<Recipe>, // 能够影响的菜谱
        val newRanks: Map<Recipe, Int>, // 使用该厨具后各菜谱的新品级
        val isPossiblyOwned: Boolean // 是否可能已有
    )

    /**
     * 计算厨具推荐
     * @param chef 厨师
     * @param recipes 厨师的三个菜谱（可能为空）
     * @param allEquips 所有可用厨具
     * @param skills 技能列表
     * @param ultimateSkills 个人技法状态
     * @return 推荐结果
     */
    fun calculateRecommendation(
        chef: Chef,
        recipes: List<Recipe?>,
        allEquips: List<Equip>,
        skills: List<Skill>,
        ultimateSkills: UltimateSkillsState,
        allChefs: List<Chef>,
        allRecipes: List<Recipe>
    ): RecommendationResult {
        // 过滤出有效的菜谱
        val validRecipes = recipes.filterNotNull()

        if (validRecipes.isEmpty()) {
            return RecommendationResult(
                needRecommendation = false,
                targetRecipes = emptyList(),
                recommendedEquips = emptyList()
            )
        }

        // 使用传入的厨师数据（已经包含个人技法和厨师间技法影响）
        val enhancedChef = if (ultimateSkills.stirfry == 0 && ultimateSkills.boil == 0 &&
                              ultimateSkills.knife == 0 && ultimateSkills.fry == 0 &&
                              ultimateSkills.bake == 0 && ultimateSkills.steam == 0) {
            // 如果ultimateSkills为空，说明技法已经应用到chef中了
            chef
        } else {
            // 否则还需要应用个人技法加成
            ChefSkillCalculator.applyPersonalSkills(chef, ultimateSkills, skills)
        }

        // 计算当前所有菜谱的品级
        val currentRanks = validRecipes.associateWith { recipe ->
            RecipeRankCalculator.calculateRecipeRank(enhancedChef, recipe)
        }

        // 分类菜谱：已达到神级的和需要提升的
        val alreadyGodTierRecipes = validRecipes.filter { recipe ->
            currentRanks[recipe]!! >= 4 // 神级是4，传级是5
        }

        val underperformingRecipes = validRecipes.filter { recipe ->
            currentRanks[recipe]!! < 4 // 神级是4，传级是5
        }

        if (underperformingRecipes.isEmpty()) {
            // 所有菜谱都达到神级及以上，不需要推荐
            return RecommendationResult(
                needRecommendation = false,
                targetRecipes = emptyList(),
                recommendedEquips = emptyList()
            )
        }

        // 尝试找到能提升多个菜谱的厨具（同时保证不降低已达到神级的菜谱）
        var targetRecipes = underperformingRecipes
        var recommendedEquips = findSuitableEquips(
            enhancedChef,
            targetRecipes,
            alreadyGodTierRecipes,
            currentRanks,
            allEquips,
            skills,
            allRecipes
        )

        // 如果没有找到能同时提升所有菜谱的厨具，分别为每个菜谱找厨具
        if (recommendedEquips.isEmpty() && targetRecipes.size > 1) {
            val allRecommendations = mutableListOf<EquipRecommendation>()
            val successfulTargets = mutableListOf<Recipe>()
            
            // 为每个菜谱单独找厨具
            for (recipe in targetRecipes) {
                val singleRecipeRecommendations = findSuitableEquips(
                enhancedChef,
                    listOf(recipe), // 只针对单个菜谱
                alreadyGodTierRecipes,
                currentRanks,
                allEquips,
                skills,
                    allRecipes
            )
                
                if (singleRecipeRecommendations.isNotEmpty()) {
                    allRecommendations.addAll(singleRecipeRecommendations)
                    successfulTargets.add(recipe)
                }
            }
            
            // 更新目标菜谱和推荐结果
            targetRecipes = successfulTargets
            recommendedEquips = allRecommendations
        }

        return RecommendationResult(
            needRecommendation = targetRecipes.isNotEmpty(),
            targetRecipes = targetRecipes,
            recommendedEquips = recommendedEquips
        )
    }

    /**
     * 查找合适的厨具
     * @param chef 厨师（已应用个人技法加成）
     * @param targetRecipes 目标菜谱列表（需要提升的菜谱）
     * @param alreadyGodTierRecipes 已达到神级的菜谱列表
     * @param currentRanks 当前所有菜谱的品级
     * @param allEquips 所有可用厨具
     * @param skills 技能列表
     * @param allRecipes 所有菜谱列表
     * @return 推荐的厨具列表，按技法加成由低到高排序
     */
    private fun findSuitableEquips(
        chef: Chef,
        targetRecipes: List<Recipe>,
        alreadyGodTierRecipes: List<Recipe>,
        currentRanks: Map<Recipe, Int>,
        allEquips: List<Equip>,
        skills: List<Skill>,
        allRecipes: List<Recipe>
    ): List<EquipRecommendation> {
        val recommendations = mutableListOf<EquipRecommendation>()

        for (equip in allEquips) {
            // 应用厨具技法加成
            val chefWithEquip = ChefSkillCalculator.applyEquipSkills(chef, equip, skills)

            // 检查是否所有目标菜谱都能达到神级及以上
            val canImproveAll = targetRecipes.all { recipe ->
                val rank = RecipeRankCalculator.calculateRecipeRank(chefWithEquip, recipe)
                rank >= 4 // 神级及以上
            }

            // 检查已达到神级的菜谱是否会降级
            val willNotDowngradeGodTier = alreadyGodTierRecipes.all { recipe ->
                val newRank = RecipeRankCalculator.calculateRecipeRank(chefWithEquip, recipe)
                val currentRank = currentRanks[recipe] ?: 0
                newRank >= currentRank // 新品级不能低于当前品级
            }

            // 只有当能提升目标菜谱且不会降低已达到神级的菜谱时，才推荐该厨具
            if (canImproveAll && willNotDowngradeGodTier) {
                // 计算该厨具对各菜谱的新品级
                val newRanks = targetRecipes.associateWith { recipe ->
                    RecipeRankCalculator.calculateRecipeRank(chefWithEquip, recipe)
                }

                // 计算总技法加成值
                val totalSkillBonus = calculateTotalSkillBonus(equip, skills)

                // 判断厨具是否可能已有
                val isPossiblyOwned = isPossiblyOwnedEquip(equip, allRecipes)

                recommendations.add(
                    EquipRecommendation(
                        equip = equip,
                        totalSkillBonus = totalSkillBonus,
                        affectedRecipes = targetRecipes,
                        newRanks = newRanks,
                        isPossiblyOwned = isPossiblyOwned
                    )
                )
            }
        }

        // 按优先级排序：1.新手奖池优先 2.可能已有优先 3.星级由低到高 4.技法加成由低到高
        return recommendations.sortedWith(
            compareBy<EquipRecommendation> { recommendation ->
                // 新手奖池优先（origin包含"新手奖池"的排在前面）
                if (recommendation.equip.origin.contains("新手奖池")) 0 else 1
            }.thenBy { recommendation ->
                // 可能已有优先（isPossiblyOwned为true的排在前面）
                if (recommendation.isPossiblyOwned) 0 else 1
            }.thenBy { it.equip.rarity }
             .thenBy { it.totalSkillBonus }
        )
    }

    /**
     * 计算厨具的总技法加成值（考虑正负数和复杂技能描述）
     * @param equip 厨具
     * @param skills 技能列表
     * @return 总技法加成值（可能为负数）
     */
    private fun calculateTotalSkillBonus(equip: Equip, skills: List<Skill>): Int {
        var totalBonus = 0

        for (skillId in equip.skill) {
            val skill = skills.find { it.skillId == skillId }
            if (skill != null) {
                val skillDesc = skill.desc

                // 处理全技法（优先处理）
                if (skillDesc.contains("全技法")) {
                    val value = extractSkillValueForType(skillDesc, "全技法")
                    totalBonus += value * 6 // 全技法影响6个技法
                } else {
                    // 处理各项单独技法（支持复合技法描述）
                    val skillTypes = listOf("炒技法", "煮技法", "切技法", "炸技法", "烤技法", "蒸技法")
                    
                    for (skillType in skillTypes) {
                        if (skillDesc.contains(skillType)) {
                            val value = extractSkillValueForType(skillDesc, skillType)
                            totalBonus += value
                        }
                    }
                }
            }
        }

        return totalBonus
    }

    /**
     * 从技能描述中提取数值（包含正负号）
     * 例如："炒技法+100" -> 100, "蒸技法-200" -> -200
     */
    private fun extractSkillValue(skillDesc: String): Int {
        val regex = Regex("([+\\-]?\\d+)")
        val matchResult = regex.find(skillDesc)
        return matchResult?.groupValues?.get(1)?.toIntOrNull() ?: 0
    }

    /**
     * 从技能描述中提取特定技法类型的数值
     * 例如："蒸技法+200 烤技法-50 煮技法-50" + "烤技法" -> -50
     */
    private fun extractSkillValueForType(skillDesc: String, skillType: String): Int {
        // 构建正则表达式来匹配特定技法类型的数值
        val regex = Regex("${skillType}([+\\-]?\\d+)")
        val matchResult = regex.find(skillDesc)
        return matchResult?.groupValues?.get(1)?.toIntOrNull() ?: 0
    }

    /**
     * 获取推荐结果的描述文本
     * @param result 推荐结果
     * @return 描述文本
     */
    fun getRecommendationDescription(result: RecommendationResult): String {
        if (!result.needRecommendation) {
            return "所有菜谱都已达到神级及以上，无需厨具推荐"
        }

        if (result.recommendedEquips.isEmpty()) {
            return "未找到合适厨具来把菜谱提升至神级"
        }

        val targetRecipeNames = result.targetRecipes.joinToString("、") { it.name }
        val equipCount = result.recommendedEquips.size
        
        return "为提升「${targetRecipeNames}」至神级及以上，推荐 ${equipCount} 个厨具"
    }

    /**
     * 获取厨具推荐的详细描述
     * @param recommendation 厨具推荐
     * @return 详细描述
     */
    fun getEquipRecommendationDescription(recommendation: EquipRecommendation): String {
        val equipName = recommendation.equip.name
        val totalBonus = recommendation.totalSkillBonus
        val recipeNames = recommendation.affectedRecipes.joinToString("、") { it.name }
        
        val rankDescriptions = recommendation.newRanks.map { (recipe, rank) ->
            val rankText = RecipeRankCalculator.getRankShortText(rank)
            "${recipe.name}(${rankText})"
        }.joinToString("、")
        
        return "${equipName} (技法+${totalBonus}) → ${rankDescriptions}"
    }

    /**
     * 判断厨具是否可能已有
     * 根据厨具来源，判断已获得的菜谱中有没有和该厨具来源相同的菜谱
     */
    private fun isPossiblyOwnedEquip(equip: Equip, allRecipes: List<Recipe>): Boolean {
        // 拆分厨具的所有来源
        val equipOrigins = equip.origin.replace("<br>", "、").split("、").map { it.trim() }
        
        // 检查是否包含奖池来源
        val hasPoolOrigin = equipOrigins.any { origin ->
            origin.contains("新手奖池") || 
            origin.contains("中级奖池") || 
            origin.contains("高级奖池") || 
            origin.contains("碧池")
        }
        
        if (hasPoolOrigin) {
            return true
        }

        // 检查是否包含默认可能拥有的来源
        val hasDefaultPossibleOrigin = equipOrigins.any { origin ->
            origin.contains("实验室") || origin.contains("厨神")
        }
        
        // 检查是否有已获得的菜谱来源包含厨具任一来源
        val hasMatchingRecipeOrigin = equipOrigins.any { equipOrigin ->
            allRecipes.any { recipe ->
                recipe.got && recipe.origin.contains(equipOrigin)
        }
        }

        return hasDefaultPossibleOrigin || hasMatchingRecipeOrigin
    }
}
